程序员成长之旅 |
您所在的位置:网站首页 › 同步消息和异步消息的区别 android › 程序员成长之旅 |
程序员成长之旅——同步IO和异步IO(五种IO模型)
同步和异步同步异步
消息通知场景比喻阻塞和非阻塞阻塞非阻塞
事例同步IO阻塞IO非阻塞IO信号驱动IO多路转接IO
异步IO五种IO模型比对钓鱼解析其五种IO模型
在这里首先要知道一点就是IO操作其实总的就分为两种,第一种是等待的时间,第二种就是数据的拷贝,而往往等待的时间都是高于数据拷贝的,因此为了IO的更加高效,我们都是通过来缩短等待的时间来提生IO的效率的。其次在学习五种IO模型的前提下,先了解一下其概念。同步,异步,阻塞和非阻塞。 同步和异步这两个概念与消息的通知机制有关。 同步所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。比如,调用readfrom系统调用时,必须等待IO操作完成后才能返回。它是一个可靠的任务序列。 异步异步的概念和其同步的概念是与之对应的,当一个异步过程调用发出后,调用者不能立即得到结果。实际处理这个调用的部件在完成后,通过状态、通知、和回调来告诉调用者。实际处理的是否完成此任务,它是不得而知的,因此它是一个不可靠的任务序列。 消息通知上面已知异步的概念和同步的概念是与之相对的。当一个同步的调用发出后,调用者要一直等待返回消息结果通知后,才能进行后续的执行;而当一个异步过程调用的时候,调用者不能立即得到返回消息。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者的。 这里提到执行部件和调用者通过三种途径返回结果:状态、通知和回调。使用那一种通知机制,依赖于执行部件的实现,除非执行部件提供多种选择,否则是不受调用者控制的。 1.如果执行部件用状态来通知,那么调用者就需要每隔一定时间检查一次,效率就很低; 2.如果使用通知的方式,效率则很高,因为执行部件几乎不需要做额外的操作。至于回调函数和通知几乎一样。 场景比喻举个例子,比如我去海底捞去吃饭,可能就有两种方式: 1.选择排队等候; 2.另外选择一个号码,等到我的号码的时候,广播通知我去就餐; 第一种:前者(排队等候)就相当于同步等待消息的通知,也就是我要一直等待前面客人用餐完。 第二种:后者(等待广播通知)就是异步等待消息通知。在异步消息处理中,等待消息通知者(在这个例子中就是等待办理业务的人)往往注册一个回调机制,在所等待的事件被触发时由触发机制(在这里是柜台的人)通过某种机制(在这里是写在小纸条上的号码,喊号)找到等待该事件的人。 阻塞和非阻塞阻塞和非阻塞与等待消息通知时的状态有关。 阻塞阻塞调用是指调用返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。 阻塞和同步是两种不同的概念。首先同步是对于消息的通知机制而言,阻塞是针对等待时的状态来说的。而且对于同步调用来说,很多时候当前线程还是激活的,只是逻辑上当前没有返回而已。 非阻塞非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回,并设置相应的errno。 虽然表面上看非阻塞的方式可以明显的提高CPU的利用率,但是也带了另外一种后果就是系统的线程切换增加。增加的CPU执行时间能不能补偿系统的切换成本需要好好评估。 事例以小王下载文件为例,对上述概念做以理解: 1.同步阻塞:小王一直盯着下载进度条,到100%的时候就完成。 同步:等待下载完成通知; 阻塞:等待下载完成通知过程中,不能做其它任务处理; 2.同步非阻塞:小王提交下载任务后就去干别的,每过一段时间就去瞄一眼进度条,看是否完成。 同步:等待下载完成通知; 非阻塞:等待下载完成通知过程中,去看动漫去了,只是时不时会瞄一眼进度条;【小王必须在两个任务操作中来回切换,关注下载进度】 3.异步阻塞:小王打开了下载完成后的提示音,下载完成会通知他,不过在这期间,他一直会等待这个声音。 异步:下载完成后的提示音; 阻塞:等待提示音的过程中,不能做其它任务处理; 4.异步非阻塞小王打开了下载完成后的提示音,下载完成会通知他,不过在这期间,他可以去干其它事情。 异步:下载完成后的提示音; 非阻塞:等待提示音的过程中,去干其它事情了,只需要接收提示音的通知; 同步IO 阻塞IO同步阻塞IO模型是最常用、最简单的模型。在Linux下,默认情况下,所有套接字都是阻塞的。下面以阻塞套接字的recvfrom的调用图来说明阻塞: 与阻塞式I/O不同的是,非阻塞的recvform系统调用调用之后,进程并没有被阻塞,内核马上返回给进程,如果数据还没准备好,此时会返回一个error(EAGAIN 或 EWOULDBLOCK)。进程在返回之后,可以处理其他的业务逻辑,过会儿再发起recvform系统调用。采用轮询的方式检查内核数据,直到数据准备好。再拷贝数据到进程,进行数据处理。 在linux下,可以通过设置socket套接字选项使其变为非阻塞。下图是非阻塞的套接字的recvfrom操作 允许socket进行信号驱动IO,并注册一个信号处理函数,进程继续运行并不阻塞。当数据准备好的时候,进程会收到一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据。 IO 多路复用的好处就在于单个进程就可以同时处理多个网络连接的IO。它的基本原理就是不再由应用程序自己监视连接,取而代之由内核替应用程序监视文件描述符。 上述四种IO模型都是同步的。相对于同步IO,异步IO不是顺序执行。用户进程进行aio_read系统调用之后,就可以去处理其他的逻辑了,无论内核数据是否准备好,都会直接返回给用户进程,不会对进程造成阻塞。等到数据准备好了,内核直接复制数据到进程空间,然后从内核向进程发送通知,此时数据已经在用户空间了,可以对数据进行处理了。 IO两个阶段,进程都是非阻塞的。 五种IO模型比对
阻塞IO 张三去钓鱼的时候,他只有一个鱼钩,当他将鱼钩放上鱼饵放入水里的那一刻起,他就一直在等待,只专注与这一件事情,直到有鱼咬住鱼饵,他拉起来,表示这个过程完成。 非阻塞IO 李四去钓鱼的时候,同样是只有一个鱼钩,当他放入水里的那一刻之后,没有鱼儿上钩的话,他会拉起来鱼钩,然后修整一下,可以干一下其他事情,之后一直重复这个动作,直到鱼儿上钩,表示这个过程完成。 信号驱动IO 王五去钓鱼的时候,同样是一个鱼钩,但不同的是他钓鱼的同时,将鱼钩上绑了一个铃铛,在此期间,他还可以和李四交流,一旦铃铛响了,他拉上来之后代表完成。 多路转接IO 马六他有多个鱼竿,假设他可以忙的过来,只要有一个鱼竿有响应,他就可以拉起来了,这个概率就相对比比较大了。 异步IO 田七去钓鱼的时候,刚拿起装备,这时候有急事呼叫他,但与此同时他还想吃钓到的鱼,这时候,他就可以雇人帮他钓鱼,等钓好之后打电话通知他,将其装备鱼给他,就代表这个过程完成了。 参考网址 以上有任何问题的,欢迎大佬们指正 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |